import Command
import qualified Git
+import qualified Git.Types as Git
+import qualified Git.Ref as Git
import qualified Annex
import qualified Remote.Compute
import qualified Types.Remote as Remote
import Annex.CatFile
import Annex.Content.Presence
import Annex.Ingest
+import Annex.GitShaKey
import Types.KeySource
import Types.Key
import Messages.Progress
Just v -> isReproducible v
Nothing -> Remote.Compute.computeReproducible state
-getInputContent :: Bool -> OsPath -> Annex (Key, Maybe OsPath)
+getInputContent :: Bool -> OsPath -> Annex (Key, Maybe (Either Git.Sha OsPath))
getInputContent fast p = catKeyFile p >>= \case
- Just inputkey -> getInputContent' fast inputkey (fromOsPath p)
- Nothing -> ifM (liftIO $ doesFileExist p)
- ( giveup $ "The computation needs an input file that is not an annexed file: " ++ fromOsPath p
- , giveup $ "The computation needs an input file which does not exist: " ++ fromOsPath p
- )
-
-getInputContent' :: Bool -> Key -> String -> Annex (Key, Maybe OsPath)
-getInputContent' fast inputkey filedesc = do
- obj <- calcRepo (gitAnnexLocation inputkey)
- if fast
- then return (inputkey, Nothing)
- else ifM (inAnnex inputkey)
- ( return (inputkey, Just obj)
- , giveup $ "The computation needs the content of a file which is not present: " ++ filedesc
+ Just inputkey -> getInputContent' fast inputkey filedesc
+ Nothing -> inRepo (Git.fileRef p) >>= \case
+ Just fileref -> catObjectMetaData fileref >>= \case
+ Just (sha, _, t)
+ | t == Git.BlobObject ->
+ getInputContent' fast (gitShaKey sha) filedesc
+ | otherwise ->
+ badinput $ ", not a git " ++ decodeBS (Git.fmtObjectType t)
+ Nothing -> notcheckedin
+ Nothing -> notcheckedin
+ where
+ filedesc = fromOsPath p
+ badinput s = giveup $ "The computation needs an input file " ++ s ++ ": " ++ fromOsPath p
+ notcheckedin = badinput "that is not checked into the git repository"
+
+getInputContent' :: Bool -> Key -> String -> Annex (Key, Maybe (Either Git.Sha OsPath))
+getInputContent' fast inputkey filedesc
+ | fast = return (inputkey, Nothing)
+ | otherwise = case keyGitSha inputkey of
+ Nothing -> ifM (inAnnex inputkey)
+ ( do
+ obj <- calcRepo (gitAnnexLocation inputkey)
+ return (inputkey, Just (Right obj))
+ , giveup $ "The computation needs the content of an annexed file which is not present: " ++ filedesc
)
+ Just sha -> return (inputkey, Just (Left sha))
{- Types of objects that can be stored in git. -}
data ObjectType = BlobObject | CommitObject | TreeObject
- deriving (Show)
+ deriving (Show, Eq)
readObjectType :: S.ByteString -> Maybe ObjectType
readObjectType "blob" = Just BlobObject
import Annex.UUID
import Annex.Content
import Annex.Tmp
+import Annex.GitShaKey
+import Annex.CatFile
import Logs.MetaData
import Logs.EquivilantKeys
import Utility.Metered
import Utility.Tmp.Dir
import Utility.Url
import Utility.MonotonicClock
-import qualified Git
-import qualified Utility.SimpleProtocol as Proto
import Types.Key
import Backend
+import qualified Git
+import qualified Utility.FileIO as F
+import qualified Utility.SimpleProtocol as Proto
import Network.HTTP.Types.URI
import Data.Time.Clock
:: ComputeProgram
-> ComputeState
-> ImmutableState
- -> (OsPath -> Annex (Key, Maybe OsPath))
+ -> (OsPath -> Annex (Key, Maybe (Either Git.Sha OsPath)))
-> (ComputeState -> OsPath -> NominalDiffTime -> Annex v)
-> Annex v
runComputeProgram (ComputeProgram program) state (ImmutableState immutablestate) getinputcontent cont =
let knowninput = M.member f' (computeInputs state')
checksafefile tmpdir subdir f' "input"
checkimmutable knowninput "inputting" f' $ do
- (k, mp) <- getinputcontent f'
- mp' <- liftIO $ maybe (pure Nothing)
- (Just <$$> relPathDirToFile subdir)
- mp
+ (k, inputcontent) <- getinputcontent f'
+ mp <- case inputcontent of
+ Nothing -> pure Nothing
+ Just (Right f'') -> liftIO $
+ Just <$> relPathDirToFile subdir f''
+ Just (Left gitsha) -> do
+ liftIO . F.writeFile (subdir </> f')
+ =<< catObject gitsha
+ return (Just f')
liftIO $ hPutStrLn (stdinHandle p) $
- maybe "" fromOsPath mp'
+ maybe "" fromOsPath mp
liftIO $ hFlush (stdinHandle p)
return $ if immutablestate
then state
getinputcontent state f =
case M.lookup (fromOsPath f) (computeInputs state) of
- Just inputkey -> do
- obj <- calcRepo (gitAnnexLocation inputkey)
- -- XXX get input object when not present
- return (inputkey, Just obj)
+ Just inputkey -> case keyGitSha inputkey of
+ Nothing -> do
+ obj <- calcRepo (gitAnnexLocation inputkey)
+ -- XXX get input object when not present
+ return (inputkey, Just (Right obj))
+ Just gitsha ->
+ return (inputkey, Just (Left gitsha))
Nothing -> error "internal"
computeskey state =
* autoinit security
-* Support non-annexed files as inputs to computations.
-
* addcomputed should honor annex.addunlocked.
* Perhaps recompute should write a new version of a file as an unlocked
file when the file is currently unlocked?
+* compute on files in submodules
+
* recompute could ingest keys for other files than the one being
recomputed, and remember them. Then recomputing those files could just
use those keys, without re-running a computation. (Better than --others
# DESCRIPTION
-Adds files to the annex that are computed from input files,
-using a compute special remote.
+Adds files to the annex that are computed from input files in the
+repository, using a compute special remote.
Once a file has been added to a compute remote, commands
like `git-annex get` will use it to compute the content of the file.